import { NextRequest, NextResponse } from 'next/server';
import { withMiddleware } from '@/lib/middleware/entry';
import { prisma } from '@/lib/prisma';
import { authenticateRequest } from '@/utils/auth';
import { ChatRequest, ChatResponse } from '@/types/chat';
import { createParser } from 'eventsource-parser';

// 简单的 parser 事件类型（避免 implicit any）
type ParsedSseEvent = {
  type: 'event' | 'reconnect-interval' | 'comment';
  id?: string;
  event?: string;
  data?: string;
};

// FastGPT API 配置（URL 仍走环境变量，鉴权 key 从 contentId -> agent.secretKey 获取）
const FASTGPT_API_URL = process.env.FASTGPT_API_URL || ''

// 格式化用户数据为文本的函数
function formatStudentDataForPrompt(studentData: any) {
  if (!studentData) return '暂无学生信息';
  return `
**姓名**: ${studentData.name || '未知'}
**邮箱**: ${studentData.email || '未知'}
  `.trim();
}

// 收集用户完整数据的函数
async function collectStudentData(userId: string) {
  const user = await prisma.user.findUnique({ where: { id: userId } });
  if (!user) return {};
  return {
    name: user.nickname || user.username,
    email: user.email,
  };
}

// POST /api/client/chat/completions - 聊天对话接口
async function handlePost(request: NextRequest) {
  try {
    const authResult = await authenticateRequest(request);
    if (!authResult.success || !authResult.user) {
      return new Response(authResult.error, { status: 401 });
    }
    const { user } = authResult;
    const userId = user.id;

    const body = await request.json();
    
    // 参数校验
    if (!body || !Array.isArray(body.messages) || body.messages.length === 0) {
      return new Response('messages 参数是必需的且不能为空', { status: 400 });
    }
    if (!body.contentId) {
      return new Response('contentId 是必填参数', { status: 400 });
    }
    if (!FASTGPT_API_URL) {
      return new Response('未配置 FASTGPT_API_URL', { status: 500 });
    }

    // 通过 contentId 查询 agent.secretKey
    const content = await prisma.content.findUnique({
      where: { id: body.contentId as string },
      include: { agent: true }
    });
    console.log('content', content);
    
    if (!content || !content.agent) {
      return new Response('未找到对应的内容或智能体', { status: 400 });
    }
    const fastGptKey = content.agent.secretKey;
    const agentId = content.agent.id;

    // 生成或使用现有的 chatId
    let chatId = body.chatId;
    if (!chatId) {
      chatId = `chat_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
    }

    const studentData = await collectStudentData(userId);
    const assembledSystemPrompt = formatStudentDataForPrompt(studentData);

    const formattedMessages = body.messages.map((msg: any) => ({
      role: msg.role,
      content: msg.content,
    }));

    // 统一走 FastGPT（OpenAI 样式 SSE）
    const payload = {
      chatId,
      stream: true,
      detail: false,
      variables: body.variables || {},
      responseChatItemId: body.responseChatItemId,
      messages: [
        { role: 'system', content: assembledSystemPrompt },
        ...formattedMessages
      ]
    };

    const response = await fetch(FASTGPT_API_URL, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${fastGptKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload),
    });

    if (!response.ok) {
      const errorBody = await response.text();
      console.error(
        `API error: ${response.status} ${response.statusText}`,
        errorBody,
      );
      return new Response(
        `Error from API: ${response.statusText}. ${errorBody}`,
        {
          status: response.status,
        },
      );
    }

    const bodyStream = response.body;
    if (!bodyStream) {
      return new Response('FastGPT 无响应体', { status: 502 });
    }

    // 使用 eventsource-parser：边解析落库，边按标准 SSE 事件格式输出
    const readable = new ReadableStream({
      start(controller) {
        const reader = bodyStream.getReader();
        const decoder = new TextDecoder('utf-8');
        const encoder = new TextEncoder();
        let fullResponse = '';
        let responseChatItemId = '';

        const parser = createParser((evt: ParsedSseEvent) => {
          if (evt.type !== 'event') return;
          const ev = evt.event || 'answer';
          const data = evt.data || '';

          // 输出标准 SSE 事件
          if (data === '[DONE]') {
            controller.enqueue(encoder.encode('data: [DONE]\n\n'));
          } else {
            controller.enqueue(encoder.encode(`event: ${ev}\n`));
            controller.enqueue(encoder.encode(`data: ${data}\n\n`));
          }

          // 累计内容用于落库
          try {
            const json = JSON.parse(data);
            const content = json?.choices?.[0]?.delta?.content || '';
            if (content) fullResponse += content;
            if (json?.id) responseChatItemId = json.id;
          } catch {}
        });

        const pump = () => {
          reader.read().then(async ({ done, value }) => {
            if (done) {
              try {
                if (fullResponse) {
                  
                  await saveChatToDatabase(userId, chatId, body.messages, fullResponse, responseChatItemId, agentId,body.contentId);
                }
              } catch (e) {
                console.error('保存聊天记录失败:', e);
              }
              controller.close();
              return;
            }

            const text = decoder.decode(value!, { stream: true });
            parser.feed(text);
            pump();
          }).catch((e) => {
            console.error('SSE 转发出错:', e);
            controller.close();
          });
        };
        pump();
      }
    });

    return new NextResponse(readable, {
      status: 200,
      headers: {
        'Content-Type': 'text/event-stream;charset=utf-8',
        'Cache-Control': 'no-cache, no-transform',
        'Connection': 'keep-alive',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      },
    });
  } catch (error) {
    console.error('Error handling chat completion:', error);
    return new Response('Internal Server Error', { status: 500 });
  }
}

async function saveChatToDatabase(
  userId: string,
  chatId: string,
  messages: any[],
  assistantResponse: string,
  responseChatItemId: string,
  agentId: string,
  contentId?: string, 
) {
  const session = await prisma.chatSession.upsert({
    where: { chatId },
    update: { updatedAt: new Date(), agentId },
    create: {
      chatId,
      title: messages.find(msg => msg.role === 'user')?.content.slice(0, 20) || '新对话',
      userId,
      agentId,
      contentId,
    }
  });

  // 确保 chatItemId 唯一
  async function generateChatItemId(prefix: string): Promise<string> {
    return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
  }

  async function ensureUniqueChatItemId(desiredId: string | undefined, prefix: 'msg' | 'assistant'): Promise<string> {
    let candidate = desiredId && desiredId.trim().length > 0 ? desiredId : await generateChatItemId(prefix);
    // 如果已存在则重新生成
    // 由于 chatItemId 有唯一索引，这里做一次 existence 检查，避免 P2002
    // 极端并发下仍可能冲突，但概率极低；如需更稳健可加入重试
    const exists = await prisma.chatMessage.findUnique({ where: { chatItemId: candidate } });
    if (!exists) return candidate;
    return await generateChatItemId(prefix);
  }

  const lastUserMessage = messages[messages.length - 1];
  const userChatItemId = await ensureUniqueChatItemId(lastUserMessage.chatItemId, 'msg');
  await prisma.chatMessage.create({
    data: {
      chatItemId: userChatItemId,
      sessionId: session.id,
      role: 'user',
      content: lastUserMessage.content,
    },
  });

  const assistantChatItemId = await ensureUniqueChatItemId(responseChatItemId, 'assistant');
  await prisma.chatMessage.create({
    data: {
      chatItemId: assistantChatItemId,
      sessionId: session.id,
      role: 'assistant',
      content: assistantResponse,
    },
  });
}

export const POST =withMiddleware(handlePost)
// OPTIONS 方法处理 CORS 预检请求
async function handleOptions() {
  return new NextResponse(null, {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
  });
}

export const OPTIONS = handleOptions;